package com.newlink.building.common_base.ext

import android.content.Intent
import android.util.Log
import com.alibaba.android.arouter.launcher.ARouter
import com.newlink.building.common_base.R
import com.newlink.building.common_base.base.BaseApplication
import com.newlink.building.common_base.base.IModel
import com.newlink.building.common_base.base.IView
import com.newlink.building.common_base.constant.Base_RouterPath
import com.newlink.building.common_base.event.MessageEvent
import com.newlink.building.common_base.event.TYPE_APP_EXIT_FORCE
import com.newlink.building.common_base.http.exception.Base_ErrorStatus
import com.newlink.building.common_base.model.bean.Base_BaseBean
import com.newlink.building.common_base.utils.NLog
import com.newlink.building.common_base.utils.NetWorkUtil
import com.newlink.building.http.function.Base_RetryWithDelay
import com.newlink.building.rx.Base_SchedulerUtils
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import org.greenrobot.eventbus.EventBus

/**
 * Created by xiaodong on 2022/7/25.
 * 后台接口请求过程扩展
 * 基础Observer
 */
fun <T : Base_BaseBean> Observable<T>.ss(
    model: IModel?,
    view: IView?,
    isShowLoading: Boolean = true,
    onSuccess: (T?) -> Unit
) {
    this.compose(Base_SchedulerUtils.ioToMain())
        .retryWhen(Base_RetryWithDelay())
        .subscribe(object : Observer<T> {
            override fun onComplete() {
                view?.hideLoading()
            }

            override fun onSubscribe(d: Disposable) {
                if (isShowLoading) view?.showLoading()
                model?.addDisposable(d)
                if (!NetWorkUtil.isNetworkConnected(BaseApplication.instance)) {
                    view?.showDefaultMsg(BaseApplication.instance.resources.getString(R.string.network_unavailable_tip))
                    onComplete()
                }
            }

            override fun onNext(t: T) {
                Log.e("fvl_dbg", "服务器返回Code  -> ${t.code}")
                Log.e("fvl_dbg", "服务器返回msg  -> ${t.msg}")
                Log.e("fvl_dbg", "服务器返回Data  -> ${t.toString()}")
                when (t.code) {
                    Base_ErrorStatus.SUCCESS -> onSuccess.invoke(t)
                    Base_ErrorStatus.TOKEN_INVALID -> {
                        // Token 过期，重新登录
                        view?.showDefaultMsg(t.msg)
                        Log.e("fvl_dbg", "Token 已过期")
                        //退出登录,清空任务栈
//                        ARouter.getInstance().build(RouterPath.PATH_LOGIN)
//                            .withAction("token_timeout")
//                            .withFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
//                            .navigation()
                        EventBus.getDefault().post(MessageEvent(TYPE_APP_EXIT_FORCE, true))

                    }

                    else -> {
                        view?.showDefaultMsg(t.msg)
                        view?.hideLoading()
                    }
                }
            }

            override fun onError(t: Throwable) {
                view?.hideLoading()
                Log.e("fvl_dbg", "fvl_dbg: onError0 $t ")
//                view?.showError(ExceptionHandle.handleException(t))
                view?.showError(BaseApplication.context.getString(R.string.network_request_error))
            }
        })
}

fun <T : Base_BaseBean> Observable<T>.sss(
    view: IView?,
    isShowLoading: Boolean = true,
    onSuccess: (T) -> Unit,
    onError: ((T) -> Unit)? = null
): Disposable {
    if (isShowLoading) view?.showLoading()
    return this.compose(Base_SchedulerUtils.ioToMain())
        .retryWhen(Base_RetryWithDelay())
        .subscribe(
            {
                when {
                    it.code == Base_ErrorStatus.SUCCESS -> onSuccess.invoke(it)
                    it.code == Base_ErrorStatus.TOKEN_INVALID -> {
                        // Token 过期，重新登录
                        view?.showDefaultMsg(it.msg)
//                        ARouter.getInstance().build(RouterPath.PATH_LOGIN)
//                            .withFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
//                            .navigation()
                        // 2023-06-13 讨论结果:  将TOKEN 过期的时间改为3个月 , 如果过期了将会退出登陆 HTTP/MQTT/SIP 服务器,并且不会自动登陆
//                        EventBus.getDefault().post(ForcedExitEvent(true))
                        EventBus.getDefault().post(MessageEvent(TYPE_APP_EXIT_FORCE, true))
                    }

                    else -> {
                        if (onError != null) {
                            onError.invoke(it)
                        } else {
                            if (it.msg.isNotEmpty())
                                view?.showDefaultMsg(it.msg)
                        }
                    }
                }
                view?.hideLoading()
            },
            {
                view?.hideLoading()
//                view?.showError(ExceptionHandle.handleException(it))
                view?.showError(BaseApplication.context.getString(R.string.network_request_error))
            }
        )
}


fun <T : Base_BaseBean> Observable<T>.registerThen(
    model: IModel?,
    view: IView?,
    isShowLoading: Boolean = true,
    onSuccess: (T) -> Unit
) {
    this.compose(Base_SchedulerUtils.ioToMain())
        .retryWhen(Base_RetryWithDelay())
        .subscribe(object : Observer<T> {
            override fun onComplete() {
                view?.hideLoading()
            }

            override fun onSubscribe(d: Disposable) {
                if (isShowLoading) view?.showLoading()
                model?.addDisposable(d)
                if (!NetWorkUtil.isNetworkConnected(BaseApplication.instance)) {
                    view?.showDefaultMsg(BaseApplication.instance.resources.getString(R.string.network_unavailable_tip))
                    onComplete()
                }
            }

            override fun onNext(t: T) {
                when {
                    t.code == Base_ErrorStatus.SUCCESS -> onSuccess.invoke(t)
                    t.code == Base_ErrorStatus.TOKEN_INVALID -> {
                        // Token 过期，重新登录
                        view?.showDefaultMsg(t.msg)
                        ARouter.getInstance().build(Base_RouterPath.PATH_LOGIN)
                            .withFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
                            .navigation()
                    }

                    else -> view?.showDefaultMsg(t.msg)
                }
            }

            override fun onError(t: Throwable) {
                view?.hideLoading()
                Log.e("fvl_dbg", "fvl_dbg: onError1 $t ")
//                view?.showError(ExceptionHandle.handleException(t))
            }
        })
}

fun <T : Base_BaseBean> Observable<T>.doNext(
    onCallback: (T) -> Unit,
    onError: (String) -> Unit
) {
    this.compose(Base_SchedulerUtils.ioToMain())
        .retryWhen(Base_RetryWithDelay())
        .subscribe(object : Observer<T> {
            override fun onComplete() {
                NLog.e("onComplete")
            }

            override fun onSubscribe(d: Disposable) {
            }

            override fun onNext(t: T) {
                NLog.e("Server Response Code -> ${t.code}  , Data -> ${t.msg}")
                when (t.code) {

                    Base_ErrorStatus.TOKEN_INVALID -> {}

                    else -> {
                        onCallback.invoke(t)
                    }

                }
            }

            override fun onError(t: Throwable) {
                Log.e("jake", "fvl_dbg: onError2 $t ")
                onError(t.message ?: "")
            }
        })
}

fun <T : Base_BaseBean> Observable<T>.doNext(
    onCallback: (T) -> Unit
) {
    this.compose(Base_SchedulerUtils.ioToMain())
        .retryWhen(Base_RetryWithDelay())
        .subscribe(object : Observer<T> {
            override fun onComplete() {
                Log.e("jake", "onComplete")
            }

            override fun onSubscribe(d: Disposable) {
            }

            override fun onNext(t: T) {
                Log.e("jake", "Server Response Code -> ${t.code}  , Data -> ${t.msg}")
                when (t.code) {

                    Base_ErrorStatus.TOKEN_INVALID -> {}

                    else -> {
                        onCallback.invoke(t)
                    }

                }
            }

            override fun onError(t: Throwable) {
                Log.e("jake", "fvl_dbg: onError2 $t ")
            }
        })
}
